#include "TonyCaptureScreen.h"
#include <QDebug>

TonyCaptureScreen::TonyCaptureScreen()
{

}
void TonyCaptureScreen::Init()
{
	isRecording = true;
	Close();
	//1 创建directx3d对象
	if (!d3d)
	{
		d3d = Direct3DCreate9(D3D_SDK_VERSION);
	}
	if (!d3d)
	{
		qDebug() << "创建directx3d对象失败";
	}
	//2 创建显卡的设备对象
	if (!device)
	{
		D3DPRESENT_PARAMETERS pa;
		ZeroMemory(&pa, sizeof(pa));
		pa.Windowed = true;
		pa.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
		pa.SwapEffect = D3DSWAPEFFECT_DISCARD;
		pa.hDeviceWindow = GetDesktopWindow();
		d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 0,
			D3DCREATE_SOFTWARE_VERTEXPROCESSING, &pa, &device
		);
		//D3DCREATE_HARDWARE_VERTEXPROCESSING
	}
	if (!device)
	{
		qDebug() << "创建设备对象失败";
	}
	//3创建离屏表面
	screenWidth = GetSystemMetrics(SM_CXSCREEN);
	screenHeight = GetSystemMetrics(SM_CYSCREEN);
	HRESULT hr;
	if (!sur)
	{
		hr = device->CreateOffscreenPlainSurface(screenWidth, screenHeight,
			D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &sur, 0);
	}
	if (!sur)
	{
		if (FAILED(hr))
		{
			//const char* errorStr = DXGetErrorString9(hr);
			//qDebug() << "离屏表面创建失败，错误信息: " << errorStr;
		}
		qDebug() << "离屏表面创建失败";
	}
	qDebug() << "屏幕抓取初始化成功";
}
void TonyCaptureScreen::OnCaptureScreen(void* data)
{
	//4 抓屏
	device->GetFrontBufferData(0, sur);
	//5 取出数据
	D3DLOCKED_RECT rect;
	ZeroMemory(&rect, sizeof(rect));
	if (sur->LockRect(&rect, 0, 0) != S_OK)
	{
		return;
	}
	memcpy(data, rect.pBits, screenWidth * screenHeight * 4);
	sur->UnlockRect();
	qDebug() << ".";
}

void TonyCaptureScreen::run()
{
	int size = screenWidth * screenHeight * 4;
	char* buf = new char[size];
	while (isRecording)
	{
		OnCaptureScreen(buf);
		screenData.push_back(buf);
		if (fps <= 0)
		{
			fps = 15;
		}
		Sleep(1000 / fps);
	}

}

std::list<char*> TonyCaptureScreen::getScreenDataList()
{
	return screenData;
}

int TonyCaptureScreen::getWidth()
{
	return screenWidth;
}

int TonyCaptureScreen::getHeight()
{
	return screenHeight;
}

int TonyCaptureScreen::getLinesize()
{
	int size = screenWidth * screenHeight * 4;
	return size;
}

void TonyCaptureScreen::Start()
{
	Init();
	this->start();
}

void TonyCaptureScreen::Stop() {
	isRecording = false;
	this->wait();//等待子线程结束
	Close();
}
void TonyCaptureScreen::Close()
{
	if (sur)
	{
		sur->Release();
		sur = nullptr;
	}
	if (device) {
		device->Release();
		device = nullptr;
	}
	if (d3d) {
		d3d->Release();
		d3d = nullptr;
	}
}
TonyCaptureScreen::~TonyCaptureScreen()
{

}
